package showtime.framework.manager.supportClasses.cycle
{
	
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import showtime.framework.core.pattern.Singleton;
	
	/** 
	 * 
	 * @author yinhao
	 * @date 2010-12-16
	 *
	 */
	
	public class CycleManager extends Singleton
	{
		/**
		 * Save the task units. 
		 */		
		private var unitMap:Object = null;
		
		private var timer:Timer = null;
		
		public function CycleManager()
		{
			super();
		}

		
		/**
		 * Get instance . 
		 * @return 
		 * 
		 */		
		static public function getInstance():CycleManager
		{
			return CycleManager(Singleton.getInstanceOrCreate(CycleManager));
			
		}
			
		/**
		 * Initialize manager.
		 * 
		 */		
		override protected function initialize():void
		{
			super.initialize();
			
			unitMap = {};
			
			timer = new Timer(0);
			timer.addEventListener(TimerEvent.TIMER, enterFrame);
			timer.start();
		}
		
		
		/**
		 * Dispose manager. 
		 * 
		 */		
		override protected function dispose():void
		{
			super.dispose();
			
			timer.stop();
			timer.removeEventListener(TimerEvent.TIMER, enterFrame);
			timer = null;
		}
		
		/**
		 * Cycye enterFrame method. 
		 * 
		 */		
		public function enterFrame(evt:TimerEvent = null):void
		{ 

			for each (var unit:ICycleUnit  in unitMap)
			{
				unit.execute();
			}
		}
		
		
		public function size():int
		{
			var i:int = 0;
			
			for each (var key:String in unitMap)
			{
				i++;
			}
			
			return i;
		}
		/**
		 * Add task to the list.
		 * 
		 */		
		public function addUnit(unit:ICycleUnit):void
		{			
			unitMap[unit.getUnitName()] = new WrapperCycleUnit(unit);
		}
		
		/**
		 * Remove task from the list. 
		 * 
		 */		
		public function removeUnit(source:ICycleUnit):void
		{
			if (unitMap.hasOwnProperty(source.getUnitName()))
			{				
				unitMap[source.getUnitName()].source = null;
				
				unitMap[source.getUnitName()] = null;
				
				delete unitMap[source.getUnitName()];	
			
			}
		}
		
		/**
		 * Get a cycle unit, witch match the key name. 
		 * @param name
		 * @return 
		 * 
		 */		
		public function getUnit(name:String):ICycleUnit
		{
			if (unitMap.hasOwnProperty(name))
			{
				return unitMap[name].source;
			}
			
			return null;
						
		}
		/**
		 * If contains cycle unit which you hoped.
		 * @param source
		 * @return 
		 * 
		 */		
		public function contains(source:ICycleUnit):Boolean
		{
			if (unitMap.hasOwnProperty(source.getUnitName()))
			{
				return true;
			}
			
			return false;
		}
		
		
	}
}